#!/usr/bin/awk -f
# @(#) ptest2html.awk 1.0 95/09/07
# 94/06/17 john h. dubois iii (john@armory.com)
# 95/09/07 Abbreviate field NAME to just "q", VALUE to the question # in hex.
# This program converts purity tests in Eric Lechner's purity test format
# to an html page that will allow a user to fill out a form & submit it for
# processing (done by the purity-test cgi script).
# This is the output of "purity format":
# The Purity Test: datafile format
#
# If you wish to create your own datafiles for the purity test,
# follow these simple intructions.
#
# Each block of text (questions, subject headers, etc.) is
# enclosed in a "bracket" type of punctuation.
#
# the styles of text blocks are:
# { plain text block }
# [ subject header ]
# ( test question )
# and < conclusion >
#
# Plain text blocks are just printed out character for character.
#
# Subject headers are prefaced by the subject number, and then
# printed as text blocks.
#
# Questions are preceeded by their numbers, and then prompt the
# user to answer the question, keeping track of the user's
# current score.
#
# Conclusions first calculate and print the user's score for the
# test, then print out the conclusion as a text block.
#
# If you wish to include any of the bracket punctuation in your
# text, the "\" character will "escape" the next character.
#
# This means that to print a question with parentheses, you
# would use the following format:
# (have you ever created your own purity test \(like this one\)?)
# the output would be this:
# 1. have you ever created your own purity test (like this one)?
# and then it would have asked the user for her/his answer.
#
# -Eric Lechner 10-26-1989
#
# -----------------sample data file------------------
# {
# Welcome to the purity test!
# Answer all the questions, and I'll tell you
# your score when you've finished the test!
# }
#
# [First subject: clown questions]
# (Can you stand on your head?)
# (Can you juggle?)
# (Do you own a pair of stilts?)
#
# [Second subject: computer programming]
# (Have you programmed a computer?)
# (Do you know more than 5 programming languages?)
# (Do you write purity test programs for fun?)
#
#
# --------------end of sample data file--------------
#
# bye.
BEGIN {
# Must process all blocks before printing anything because we have to
# know how many questions there are before printing FORM
while ((BlockType = FindBlock()) != "EOF")
ProcBlock(BlockType,Block)
if (ARGC > 1) {
Name = ARGV[1]
sub(".*/","",Name) # Get rid of path
# Push first char to upper case
Name = toupper(substr(Name,1,1)) substr(Name,2)
print "" Name " Purity Test"
}
else
print "A Purity Test"
print \
""
}
function Xprint(S) {
Questions = Questions "\n" S
}
# Sets global Block to next block, returns block type
function FindBlock( Line,EndChar,ind,C,EndPat) {
if ((Line = ReadLine()) == "")
return "EOF"
sub("^[ \t]+","",Line) # get rid of leading whitespace
ind = index("({[<",C = substr(Line,1,1))
if (!ind)
FileErrExit(\
"\nBad starting character for block (" C ") in line:\n" Line,1)
Line = substr(Line,2)
if (Line == "")
Line = "\n"
EndChar = substr(")}]>",ind,1)
EndPat = "[^\\\\]\\" EndChar
Block = ""
while (Line != "") {
if (substr(Line,1,1) == EndChar)
break
else if (match(Line,EndPat)) {
Block = Block substr(Line,1,RSTART)
break
}
else {
Block = Block Line
if (Line != "\n")
Block = Block "\n"
}
Line = ReadLine()
}
if (Line == "")
FileErrExit("Incomplete block at end of file",1)
else {
gsub(/\\/,"",Block)
return C
}
}
# Print header & open subject list
function DoHeader(Header) {
if (Header != "")
if (length(Header) > 50) # Verbose header, should be printed smaller
Xprint("
" Header "
\n")
else
Xprint("
" Header "
\n")
Xprint("
Check all boxes for which your answer is \"yes\"
")
InSubjList = 1
}
# If InQuestList == 1, there is an ordered question list pending.
function ProcBlock(BlockType,Block) {
if (BlockType == "(") { # Question
if (!InSubjList)
DoHeader("")
if (!InQuestList) {
# Open a question list
Xprint("")
InQuestList = 1
}
QuestNum++
Xprint("
" Block "
")
}
else if (BlockType == "{") { # Plain text
# Comments probably should be printed with the same line breaks
# as they had.
gsub("\n"," \n",Block)
# Guess that the first plain text will be an intro
if (!InSubjList)
DoHeader(Block)
else {
if (InQuestList)
Xprint(" ") # Break from the last question
else {
# Open a question list so that justification will be consistent
Xprint("")
InQuestList = 1
}
Xprint("" Block "")
}
}
else if (BlockType == "<") { # Conclusion
# Conclusion probably should be printed with the same line breaks
# as they had.
gsub("\n"," \n",Block)
Conclusion = "
" Block "
"
}
else if (BlockType == "[") { # Subject header
if (!InSubjList)
DoHeader("")
if (InQuestList)
Xprint("") # Finish the last question list
# Subjects probably should be printed with the same line breaks
# as they had.
gsub("\n"," \n",Block)
Xprint("
" Block "
")
DidHeader = 1
InQuestList = 0 # No longer within a question list
}
}
function ReadLine( ret) {
while ((ret = getline) > 0)
if (NF > 0)
return $0
if (ret < 0) {
print "Error reading file " FILENAME ". Exiting." | "cat 1>&2"
exit 1
}
else
return ""
}
function LineErr(S) {
ErrPrint("Error on line " FNR ": " S)
}
function FileErr(S) {
ErrPrint("Error on line " FNR " of file " FILENAME ": " S)
}
function FileErrExit(S,ExitVal) {
FileErr(S)
Err = ExitVal
exit(ExitVal)
}
#function ErrPrint(S) {
# print S | "cat 1>&2"
#}
function ErrPrint(S) {
print S > "/dev/stderr"
close("/dev/stderr") # flush output
}